package busterminalweb.action.scheduleditem;

import busterminal.entity.Route;
import busterminal.entity.RouteImplementation;
import busterminal.entity.ScheduledItem;
import busterminal.entity.ScheduledItemImplementation;
import busterminal.entity.service.DaysOfWeek;
import busterminal.entity.service.Time;
import busterminal.exception.BusinessException;
import busterminal.persistence.ScheduledItemDAO;
import busterminal.services.ServiceLocator;
import busterminalweb.action.Action;
import busterminalweb.action.ActionResult;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Сохранить пункт расписания
 */
public class SaveScheduledItemAction implements Action {

    /**
     * Регулярное выражение для проверки корректности ввода идентификатора
     */
    private static final String CORRECT_ID_FORMAT = "^[0-9]*$";
    /**
     * Регулярное выражение для проверки корректности ввода числа
     */
    private static final String CORRECT_NUMBER_FORMAT = "^[1-9]([0-9]*)$";
    /**
     * Регулярное выражение для проверки корректности ввода времени в формате
     * <code>HH:MM</code>
     */
    private static final String CORRECT_TIME_FORMAT = "^(([0-1][0-9])|([2][0-3])):([0-5][0-9])$";

    /**
     * Выполнить действие
     * @param request запрос
     * @param response ответ
     * @return страница, которой нужно передать управление
     */
    @Override
    public ActionResult execute(HttpServletRequest request, HttpServletResponse response) {
        if (request.getParameter("saveButton") != null) {
            if (!request.getParameter("id").trim().matches(CORRECT_ID_FORMAT)) {
                throw new BusinessException("Incorrect scheduled item id=" + request.getParameter("id").trim());
            }
            int id = Integer.parseInt(request.getParameter("id").trim());
            ScheduledItem scheduledItem = (id == 0) ? new ScheduledItemImplementation() : ServiceLocator.getService(ScheduledItemDAO.class).read(id);

            if (request.getParameter("route") != null && request.getParameter("route").trim().matches(CORRECT_NUMBER_FORMAT)) {
                int routeId = Integer.parseInt(request.getParameter("route").trim());
                Route route = new RouteImplementation();
                route.setId(routeId);
                scheduledItem.setRoute(route);
            } else {
                throw new BusinessException("You should define route");
            }

            if (request.getParameter("departureTime") != null && request.getParameter("departureTime").trim().matches(CORRECT_TIME_FORMAT)) {
                scheduledItem.setDepartureTime(Time.parseTime(request.getParameter("departureTime").trim()));
            } else {
                throw new BusinessException("You should define departure time in HH:MM format");
            }

            if (request.getParameter("arrivalTime") != null && request.getParameter("arrivalTime").trim().matches(CORRECT_TIME_FORMAT)) {
                scheduledItem.setArrivalTime(Time.parseTime(request.getParameter("arrivalTime").trim()));
            } else {
                throw new BusinessException("You should define arrival time in HH:MM format");
            }

            scheduledItem.setTravelTime();

            if (request.getParameter("departureTimeFromEndPoint") != null && request.getParameter("departureTimeFromEndPoint").trim().matches(CORRECT_TIME_FORMAT)) {
                scheduledItem.setDepartureTimeFromEndPoint(Time.parseTime(request.getParameter("departureTimeFromEndPoint").trim()));
            } else {
                throw new BusinessException("You should define departure time from end point in HH:MM format");
            }

            if (request.getParameter("arrivalTimeToBusTerminal") != null && request.getParameter("arrivalTimeToBusTerminal").trim().matches(CORRECT_TIME_FORMAT)) {
                scheduledItem.setArrivalTimeToBusTerminal(Time.parseTime(request.getParameter("arrivalTimeToBusTerminal").trim()));
            } else {
                throw new BusinessException("You should define arrival time to bus terminal in HH:MM format");
            }

            if (request.getParameterValues("routingDays") != null && request.getParameterValues("routingDays").length != 0) {
                String[] routingDays = request.getParameterValues("routingDays");
                List<DaysOfWeek> daysOfWeek = new ArrayList<DaysOfWeek>();
                for (String day : routingDays) {
                    daysOfWeek.add(DaysOfWeek.valueOf(day.toUpperCase()));
                }
                scheduledItem.setRoutingDays(daysOfWeek);
            } else {
                throw new BusinessException("You should define routing days");
            }

            if (request.getParameter("platformNumber") != null && request.getParameter("platformNumber").trim().matches(CORRECT_NUMBER_FORMAT)) {
                scheduledItem.setPlatformNumber(Integer.parseInt(request.getParameter("platformNumber").trim()));
            } else {
                throw new BusinessException("You should define platform number");
            }

            ScheduledItemDAO scheduledItemDAO = ServiceLocator.getService(ScheduledItemDAO.class);
            if (id != 0) {
                scheduledItemDAO.update(scheduledItem);
            } else {
                scheduledItemDAO.create(scheduledItem);
            }
        }

        //список, который нужно загрузить при возврате на главную страницу
        request.getSession().setAttribute("showPage", "scheduled-item-list");

        //main - это action, который никак сервлетом не обрабатывается,
        //т.е. открывается главная страница
        return ActionResult.redirect("main");
    }

    /**
     * Получить имя действия
     * @return имя действия
     */
    @Override
    public String getName() {
        return "scheduled.item.save";
    }
}
